This document describes the  steps required to enhance the Delphi TTreeView component so that:
a) its behavior at design time is the same as at run time,
b) drag'n drop at design time becomes possible and
c) the use of different colors and fonts for different nodes becomes possible.

Although TTreeview is very useful, Borland has simply not implemented some very important properties 
and so you have to do it yourself. But that's quite simple (once you know it). The included units
make the described enhancements clearer.

a) 
To make TTreeView (and also all other components, which don't do that by default) able to receive
messages at design time (in short DT) at all, you have to catch the CM_DESIGNHITTEST message and
must return an appropriate answer.  If a component should accept DT-messages, then you have to return
the value 1 in the field Message.Return. But you shouldn't globally accept all the messages, since
the normal DT-handling wouldn't work any longer (e.g. moving the component around the form). So
you should make your answer dependent on a condition (e.g. whether a node is under the mouse), as 
shown in the source code.
To make scrolling work, there's another message to catch: WM_NCHITTEST. The Component receives this 
message immediately after it is determined that it should generally get such messages
(by CM_DESIGNHITTEST). To produce the same behavior as at run time, the message WM_NCHITTEST must
not be handled by the inherited handlers of WinControl etc., but must be given directly to the 
default handler (see source code).

b)
As a matter of principle drag'n drop should work after the change described in point a) has been 
made, but Borland has established another handicap. While a drag'n drop action is in progress, the 
mouse messages are received by a hidden window, which sends, on its part, enhanced messages to the
control (drag over, drag enter etc.). These will be sent as CM_DRAG messages and are filtered by the 
VCL at DT. That means for us, we have to send CM_DRAG on its normal way before the VCL prevents that.
This happens by executing:
	IF Message.Msg = CM_DRAG THEN Dispatch(Message) ELSE INHERITED WndProc(Message);
in our (overridden) WndProc.

c) 
The lack of the possibility to adapt TTreeView (and all other common controls) to your own needs
is Microsoft's fault, not Borland's, since it's only been available for a short period of time (I
believe since IE 3.0, which came with a new CommCtrl.DLL). The point here is not to draw the 
entire control by yourself (that's much too expensive), but only to change some aspects of it, like
the font color, the font type or even another background (like the button panel in IE 3.0).

The principle is as follows:

- Each common control sends during its repaint (aka paint cycle) a WM_NOTIFY message to its parent
window, with the code NM_CUSTOMDRAW in the field Message.NMHdr^.code (see also declaration of the
TWMNotify record). Note: Since many controls send messages to their parent window, which isn't
predetermined and can be combined in any way, Delphi lets all window components send back certain 
messages as so-called component messages (CM_) or component notifications (CN_) to the calling child
window. Thus the child window can handle these message by itself. This is also true for WM_NOTIFY 
(sent by Windows), which returns as CN_NOTIFY (sent by the parent window).

- The control can handle this message and so change its (default) appearance. You can read more about
this subject at the address below. In our case we want to change the color or the font of
the nodes (say depending on their level). So it returns Message.Result:=CDRF_NOTIFYITEMDRAW; when it
receives the code CDDS_PREPAINT (which is the first during the paint cycle) and tells Windows its wish
to change the default behavior.

- Now TTreeView receives for each node repaint a CN_NOTIFY message with the code CDDS_ITEMPREPAINT.
With the message structur comes a valid device context, whose properties can now be changed, eg.
by selecting a new font into the DC:
	SelectObject(nmcd.hdc,TempFont.Handle);
After that you have to mark this change by:
	Message.Result:=CDRF_NEWFONT;
If you don't change the font, but only the color (brush etc.) this is not necessary and we return:
	Message.Result:=CDRF_DODEFAULT;

And that's all for this case. More details can be obtained from MSDN Online (www.microsoft.com/msdn, 
it is free).

You will find the corresponding documents under this path in the tree java applet:

Microsoft Developer Network Online Library
+ SDK Documentation
  + Internet/Intranet/Extranet Services
    + Memphis and Windows NT 5.0 Shell Preview
      + Internet Application Development
        + Application and Internet Services
          + Common Controls API
            + Custom Draw

Look closer at this path and you will easily guess why the information described here isn't widely known. 
BTW: The custom draw technique works already, even when you find the documents under "Windows 5.0" 
and "Internet".


And now, I wish you happy coding

Dipl.-Ing. Mike Lischke
